use anyhow::Result;
use git2::{BranchType, Repository, StatusOptions};
use tokio::task;

pub mod branch;
pub mod commit;
pub mod status;

pub use commit::*;
pub use branch::*;

// 公共函数，检查是否在 Git 仓库中
pub async fn is_git_repository() -> bool {
    task::spawn_blocking(|| Repository::open(".").is_ok())
        .await
        .unwrap_or(false)
}

// 获取当前分支名称
pub async fn get_current_branch() -> Result<String> {
    task::spawn_blocking(|| {
        let repo = Repository::open(".")?;

        let head = repo.head()?;
        if head.is_branch() {
            if let Some(name) = head.shorthand() {
                return Ok(name.to_string());
            }
        }

        // 如果HEAD是分离状态
        Ok("HEAD detached".to_string())
    })
    .await?
}

// 获取所有分支
pub async fn get_branches() -> Result<Vec<String>> {
    task::spawn_blocking(|| {
        let repo = Repository::open(".")?;
        let branches = repo.branches(Some(BranchType::Local))?;

        let mut branch_names = Vec::new();
        for branch_result in branches {
            let (branch, _) = branch_result?;
            if let Some(name) = branch.name()? {
                branch_names.push(name.to_string());
            }
        }

        Ok(branch_names)
    })
    .await?
}

// 获取仓库状态
pub async fn get_repository_status() -> Result<RepositoryStatus> {
    task::spawn_blocking(|| {
        let repo = Repository::open(".")?;
        let mut status_options = StatusOptions::new();
        status_options
            .include_untracked(true)
            .recurse_untracked_dirs(true);

        let statuses = repo.statuses(Some(&mut status_options))?;

        // 统计各类文件状态
        let mut status = RepositoryStatus {
            untracked: Vec::new(),
            modified: Vec::new(),
            staged: Vec::new(),
            conflicted: Vec::new(),
        };

        for entry in statuses.iter() {
            let path = match entry.path() {
                Some(p) => p.to_string(),
                None => continue,
            };

            let status_flags = entry.status();

            if status_flags.is_index_new() || status_flags.is_index_modified() ||
               status_flags.is_index_deleted() || status_flags.is_index_renamed() ||
               status_flags.is_index_typechange() {
                status.staged.push(path.clone());
            }

            if status_flags.is_wt_modified() || status_flags.is_wt_deleted() ||
               status_flags.is_wt_renamed() || status_flags.is_wt_typechange() {
                status.modified.push(path.clone());
            }

            if status_flags.is_wt_new() {
                status.untracked.push(path.clone());
            }

            if status_flags.is_conflicted() {
                status.conflicted.push(path.clone());
            }
        }

        Ok(status)
    })
    .await?
}

// 仓库状态结构体
#[derive(Debug, Clone)]
pub struct RepositoryStatus {
    pub untracked: Vec<String>,
    pub modified: Vec<String>,
    pub staged: Vec<String>,
    pub conflicted: Vec<String>,
}
